package cn.pda.serialport;

import android.content.Context;
import android.telephony.TelephonyManager;

import java.lang.reflect.Method;
import java.math.BigInteger;

public class Tools {

    /**
     * CRC 算法
     * @param data
     * @return
     */
    public static String getCrc(byte[] data) {
        int high;
        int flag;
        // 16位寄存器，所有数位均为1
        int wcrc = 0xffff;
        for (int i = 0; i < data.length; i++) {
            // 16 位寄存器的高位字节
            high = wcrc >> 8;
            // 取被校验串的一个字节与 16 位寄存器的高位字节进行“异或”运算
            wcrc = high ^ data[i];
            for (int j = 0; j < 8; j++) {
                flag = wcrc & 0x0001;
                // 把这个 16 寄存器向右移一位
                wcrc = wcrc >> 1;
                // 若向右(标记位)移出的数位是 1,则生成多项式 1010 0000 0000 0001 和这个寄存器进行“异或”运算
                if (flag == 1)
                    wcrc ^= 0xa001;
            }
        }
        return Integer.toHexString(wcrc);
    }

    private static String getCrc16(byte[] arr_buff) {
        int len = arr_buff.length;

        // 预置 1 个 16 位的寄存器为十六进制FFFF, 称此寄存器为 CRC寄存器。
        int crc = 0xFFFF;
        int i, j;
        for (i = 0; i < len; i++) {
            // 把第一个 8 位二进制数据 与 16 位的 CRC寄存器的低 8 位相异或, 把结果放于 CRC寄存器
            crc = ((crc & 0xFF00) | (crc & 0x00FF) ^ (arr_buff[i] & 0xFF));
            for (j = 0; j < 8; j++) {
                // 把 CRC 寄存器的内容右移一位( 朝低位)用 0 填补最高位, 并检查右移后的移出位
                if ((crc & 0x0001) > 0) {
                    // 如果移出位为 1, CRC寄存器与多项式A001进行异或
                    crc = crc >> 1;
                    crc = crc ^ 0xA001;
                } else
                    // 如果移出位为 0,再次右移一位
                    crc = crc >> 1;
            }
        }
        return Integer.toHexString(crc);
    }

    /**
     * 获取手机IMEI
     * @param context
     * @return
     */
    public static final String getIMEI(Context context) {
        try {
            //实例化TelephonyManager对象
            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            //获取IMEI号

            Method method = telephonyManager.getClass().getMethod("getImei", int.class);
            String  imei = (String) method.invoke(telephonyManager, 0);
//            String imei = telephonyManager.getDeviceId();
            //在次做个验证，也不是什么时候都能获取到的啊
            if (imei == null) {
                imei = "";
            }
            return imei;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
    /**
     * 获取手机IMSI
     */
    public static String getIMSI(Context context){
        try {
            TelephonyManager telephonyManager=(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
            //获取IMSI号
            Method method = telephonyManager.getClass().getMethod("getImsi", int.class);
            String  imsi = (String) method.invoke(telephonyManager, 0);
//            String imsi=telephonyManager.getSubscriberId();
            if(null==imsi){
                imsi="";
            }
            return imsi;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * imei ccr
     * @return
     */
    public static String getIMEI_CCR(String IMEI){
        BigInteger vb = new BigInteger(IMEI);
        String cc= Long.toHexString(vb.longValue()).toUpperCase();
        return Tools.getCrc(cc.getBytes());
    }
    public static String getIMEI_CCR16(String IMEI){
        BigInteger vb = new BigInteger(IMEI);
        String cc= Long.toHexString(vb.longValue()).toUpperCase();
        return Tools.getCrc16(cc.getBytes());
    }
    /**
     * 16进制直接转换成为字符串(无需Unicode解码)
     * @param hexStr
     * @return
     */
    public static String hexStr2Str(String hexStr) {
        String str = "0123456789ABCDEF";
        char[] hexs = hexStr.toCharArray();
        byte[] bytes = new byte[hexStr.length() / 2];
        int n;
        for (int i = 0; i < bytes.length; i++) {
            n = str.indexOf(hexs[2 * i]) * 16;
            n += str.indexOf(hexs[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        return new String(bytes);
    }

    /**
     * 字符串转换成为16进制(无需Unicode编码)
     * @param str
     * @return
     */
    public static String str2HexStr(String str) {
        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;
        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
            // sb.append(' ');
        }
        return sb.toString().trim();
    }


    /**
     * 字节数组转16进制字符串
     */
    public static String bytes2HexString(byte[] b) {
        String r = "";

        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            r += hex.toUpperCase();
        }

        return r;
    }

    public static String Bytes2HexString(byte[] paramArrayOfByte, int paramInt) {
        String str1 = "";
        int i = 0;
        for (; ; ) {
            if (i >= paramInt) {
                return str1;
            }
            String str3 = Integer.toHexString(paramArrayOfByte[i] & 0xFF);
            String str2 = str3;
            if (str3.length() == 1) {
                str2 = "0" + str3;
            }
            str1 = str1 + str2.toUpperCase();
            i += 1;
        }
    }

    /**
     * 16进制表示的字符串转换为字节数组
     *
     * @param s 16进制表示的字符串
     * @return byte[] 字节数组
     */
    public static byte[] hexStringToByteArray(String s) {

        int len = s.length();
        if (len % 2 != 0) {
            s = "0" + s;
            len += 1;
        }
        byte[] b = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            // 两位一组，表示一个字节,把这样表示的16进制字符串，还原成一个字节
            b[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character
                    .digit(s.charAt(i + 1), 16));
        }
        return b;
    }
    /*
     * int转换为字节
     */
    public static byte[] intToByte(int number) {
        int temp = number;
        byte[] b = new byte[4];
        for (int i = 0; i < b.length; i++) {
            b[i] = new Integer(temp & 0xff).byteValue();// 将最低位保存在最低位
            temp = temp >> 8;// 向右移8位
        }
        byte[] bytes = reverseByteArr(b);
        return bytes;
    }
    public static byte[] reverseByteArr(byte[] bytes){
        if(bytes == null || bytes.length == 0){
            throw new RuntimeException("bytes字节数组不能为空");
        }
        byte[] b = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            b[bytes.length -i - 1] = bytes[i];
        }
        return b;
    }
    /*
     * 字符转换为字节
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /*
     * 16进制字符串转字节数组
     */
    public static byte[] hexString2Bytes(String hex) {

        if ((hex == null) || (hex.equals(""))) {
            return null;
        }
        if (hex.length() % 2 != 0) {
            hex = "0" + hex;
        }
        hex = hex.toUpperCase();
        int len = hex.length() / 2;
        byte[] b = new byte[len];
        char[] hc = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int p = 2 * i;
            b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1]));
        }
        return b;
    }

    /**
     * 高低8位连接组合数字。
     *
     * @param paramByte1
     * @param paramByte2
     * @return
     */
    public static int byteLinkByteToInt(byte paramByte1, byte paramByte2) {
        return 0xFF00 & paramByte1 << 8 | paramByte2 & 0xFF;
    }

    /**
     * 整数加小数返回int
     *
     * @param param1
     * @param param2
     * @return
     */
    public static int twoByteToInt(byte param1,byte param2){
        return param1*100+param2;
    }

    /**
     * 合成脚环id
     * @param len 固定2 高低8位组合
     */
    public static String byteLinkByteToHexString(byte[] buff, int index, int len) {
        StringBuilder builder = new StringBuilder();
        String temp;
        for (int i = 0; i < len; i++) {
            temp = Integer.toHexString(0xFF & buff[index++]);
            if (temp.length() == 1) {
                builder.append("0");
            }
            builder.append(temp);
        }
        return builder.toString().toUpperCase();
    }

    /**
     * 字节数组转16进制字符串。
     *
     * @param data
     * @return
     */
    public static String byteToHexString(byte[] data) {
        StringBuilder builder = new StringBuilder();
        String temp;
        int len = data.length;
        // TODO: 2016/12/1
        for (int i = 0; i < len; i++) {
            temp = Integer.toHexString(0xFF & data[i]);
            if (temp.length() == 1) {
                builder.append("0");
            }
            builder.append(temp);
        }
        return builder.toString().toUpperCase();
    }

    /**
     * 字节数组转字符串
     * @param data
     * @param len dataSize
     * @return
     */
    public static String byteToHexString(byte[] data, int len) {
        StringBuilder builder = new StringBuilder();
        String temp;
        //int len = data.length;
        // TODO: 2016/12/1
        for (int i = 0; i < len; i++) {
            temp = Integer.toHexString(0xFF & data[i]);
            if (temp.length() == 1) {
                builder.append("0");
            }
            builder.append(temp);
        }
        return builder.toString().toUpperCase();
    }

    /**
     * 字节数组转字符串
     * @param data
     * @param
     * @return
     */
    public static String byteToHexString(byte data) {
        StringBuilder builder = new StringBuilder();
        String temp;
        //int len = data.length;
        // TODO: 2016/12/1
            temp = Integer.toHexString(0xFF & data);
            if (temp.length() == 1) {
                builder.append("0");
            }
            builder.append(temp);
        return builder.toString().toUpperCase();
    }

    public static byte[] HexString2Bytes(String paramString) {
        int j = paramString.length() / 2;
        byte[] arrayOfByte = new byte[j];
        byte[] paramArray = paramString.getBytes();
        int i = 0;
        for (; ; ) {
            if (i >= j) {
                return arrayOfByte;
            }
            arrayOfByte[i] = uniteBytes(paramArray[(i * 2)],
                    paramArray[(i * 2 + 1)]);
            i += 1;
        }
    }

    public static int bytesToInt(byte[] paramArrayOfByte) {
        return paramArrayOfByte[0] & 0xFF | paramArrayOfByte[1] << 8 & 0xFF00
                | paramArrayOfByte[2] << 16 & 0xFF0000
                | paramArrayOfByte[3] << 25 & 0xFF000000;
    }

    public static byte[] intToBytes(int paramInt) {
        return new byte[]{(byte) (paramInt & 0xFF),
                (byte) ((0xFF00 & paramInt) >> 8),
                (byte) ((0xFF0000 & paramInt) >> 16),
                (byte) ((0xFF000000 & paramInt) >> 24)};
    }

    public static byte uniteBytes(byte paramByte1, byte paramByte2) {
        return (byte) ((byte) (Byte.decode(
                "0x" + new String(new byte[]{paramByte1})).byteValue() << 4) ^ Byte
                .decode("0x" + new String(new byte[]{paramByte2}))
                .byteValue());
    }

    public static String intToHexString(int param,int count)
    {

        StringBuilder hexString=new StringBuilder(Integer.toHexString(param));
        //不够补起，超过没管
        StringBuilder leftString=new StringBuilder();
        for (int i=hexString.length();i<count;i++)
        {
            leftString.append("0");
        }
        return leftString.append(hexString).toString();
    }
    public static String intToHexString(int param)
    {
        return intToHexString(param,2);
    }
}
